/* 
 * File:   CircularBuff.h
 * Author: lusitanio
 *
 * Created on 21 de Março de 2012, 13:12
 */

#ifndef CIRCULARBUFF_H
#define	CIRCULARBUFF_H


#include <map>
#include <iostream>
#include <vector>
using namespace std;

class CircularBuff {
private:
    vector <float> dados;
    int writeIndex;
    int readIndex;
    int itemCount;
public:



    CircularBuff(int maxElements = 1) {
        dados = *new vector<float>(maxElements);
        writeIndex = 0;
        readIndex = 0;
        itemCount = 0;
    }
    

    CircularBuff(const CircularBuff& anotherBuffer) {
        dados = *new vector<float>(anotherBuffer.dados);
        writeIndex = anotherBuffer.writeIndex;
        readIndex = anotherBuffer.readIndex;
        itemCount = anotherBuffer.itemCount;
    }
    
    ~CircularBuff(){
    }
    
    CircularBuff& operator=(const CircularBuff &m){
        if (this == &m) {
            // avoid self-assignment
            return *this;
        } else{
            if (this->dados.size() != m.dados.size()){
                this->~CircularBuff();               
            }
            dados = *new vector<float>(m.dados);
            writeIndex = m.writeIndex;
            readIndex = m.readIndex;
            itemCount = m.itemCount;
            return *this;
        }
    }

    void insert(const float& anItem){
        dados.at(writeIndex) = anItem;
        itemCount == (int)dados.size() ? : itemCount++;
        writeIndex == ((int)dados.size()-1) ? writeIndex = 0 : writeIndex++;   
    }

    void print() {
        printf("***** CircularBuff DADOS *****\n");
        printf("** TAMANHO DO VECTOR: %d\n",dados.size());
        printf("** ITENS: %d\n",itemCount);
        printf("** WriteIndex: %d\n",writeIndex);
        readIndex = writeIndex;
        for (int i = 0; i < itemCount; i++)
            printf("Dado[%d]: %f\n",i, dados.at(i));
    }    
    vector<float> getDados() const {
        vector <float> w_return = *new vector <float>(itemCount);
        for (int i = 0; i < itemCount; i++)
            w_return.at(i) = dados.at(i);        
        return w_return;
    }
    
    vector<float> getDados(int n_ele)  {
        vector <float> w_return = *new vector <float>(n_ele);
        readIndex = writeIndex;
        for (int i = 0; i < n_ele; i++){
            readIndex == 0 ? readIndex = (int)dados.size()-1 : readIndex--;
            w_return.at(i) = dados.at(readIndex);              
        }
        return w_return;
    }    

    void setDados(vector<float> dados) {
        this->dados = dados;
    }

    int getItemCount() const {
        return itemCount;
    }

    void setItemCount(int itemCount) {
        this->itemCount = itemCount;
    }

    int getReadIndex() const {
        return readIndex;
    }

    void setReadIndex(int readIndex) {
        this->readIndex = readIndex;
    }

    int getWriteIndex() const {
        return writeIndex;
    }

    void setWriteIndex(int writeIndex) {
        this->writeIndex = writeIndex;
    }
    

};


#endif	/* CIRCULARBUFF_H */

